package com.cly.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cly.base.contants.CacheKeysConstants;
import com.cly.dto.CourseDto;
import com.cly.entity.Course;
import com.cly.entity.CourseNode;
import com.cly.entity.CourseUser;
import com.cly.mapper.CourseMapper;
import com.cly.result.JsonRequest;
import com.cly.result.exception.ServiceException;
import com.cly.result.exenum.RequestException;
import com.cly.service.ICourseNodeService;
import com.cly.service.ICourseService;
import com.cly.service.ICourseUserService;
import com.cly.vo.CourseVo;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

/**
 * 课程表业务层实现
 *
 * @author 春风能解释
 * <p>
 * 2024-06-06
 */
@Service
@Slf4j
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {


    /**
     * 课节服务
     */
    @Resource
    @Lazy
    private ICourseNodeService courseNodeService;

    /**
     * 课程用户服务
     */
    @Resource
    private ICourseUserService courseUserService;

    /**
     * 根据条件查询课程表信息
     *
     * @param course 条件
     * @return JSON
     */
    @Override
    @Cacheable(value = CacheKeysConstants.CourseKeys.COURSE_ARRAY, key = "#root.args")
    public JsonRequest<List<CourseVo>> lookCourse(Integer current, Integer size, Course course) {
        IPage<CourseVo> coursePage = baseMapper.selectCoursePages(new Page<>(current, size), course);
        // 传入分页
        return JsonRequest.success(coursePage.getRecords(), coursePage.getTotal());
    }

    /**
     * 新增一条课程表信息
     *
     * @param courseDto 课程表信息
     * @return JSON
     */
    @Override
    @CacheEvict(value = {CacheKeysConstants.CourseKeys.COURSE_ARRAY, CacheKeysConstants.CourseKeys.COURSE_COUNT, CacheKeysConstants.CourseKeys.COURSE_TYPE}, allEntries = true)
    public JsonRequest<Integer> addOneCourse(CourseDto courseDto) {
        // 插入课程表信息
        int column = baseMapper.insert(courseDto);
        if (column < 1) {
            throw new ServiceException(RequestException.INSERT_ERROR);
        }
        return JsonRequest.success(column);
    }

    /**
     * 修改一条课程表信息
     *
     * @param course 课程表信息
     * @return JSON
     */
    @Override
    @CacheEvict(value = {CacheKeysConstants.CourseKeys.COURSE_ARRAY, CacheKeysConstants.CourseKeys.COURSE_COUNT, CacheKeysConstants.CourseKeys.COURSE_TYPE}, allEntries = true)
    public JsonRequest<Integer> updateOneCourse(Course course) {
        Course courseObject = baseMapper.selectById(course.getId());
        if (Objects.isNull(courseObject)) {
            return JsonRequest.error(RequestException.NOT_FOUND);
        }
        int column = baseMapper.updateById(course);
        if (column < 1) {
            throw new ServiceException(RequestException.UPDATE_ERROR);
        }
        return JsonRequest.success(column);
    }

    /**
     * 批量删除课程表信息
     *
     * @param ids 课程表id列表
     * @return JSON
     */
    @Override
    @CacheEvict(value = {CacheKeysConstants.CourseKeys.COURSE_ARRAY, CacheKeysConstants.CourseKeys.COURSE_COUNT, CacheKeysConstants.CourseKeys.COURSE_TYPE}, allEntries = true)
    public JsonRequest<Integer> deleteCourses(List<Long> ids) {
        // 查询课程表信息
        List<Course> courseList = baseMapper.selectBatchIds(ids);
        // 判断待删除的课程表信息是否存在
        if (courseList.size() != ids.size()) {
            return JsonRequest.error(RequestException.NOT_FOUND);
        }
        // 判断是否有课节信息
        long count = courseNodeService.count(Wrappers.lambdaQuery(CourseNode.class)
                .in(CourseNode::getCourseId, ids));
        // 判断是否有课节信息
        if (count > 0) {
            throw new ServiceException(RequestException.DELETE_ERROR);
        }
        int column = baseMapper.deleteByIds(ids);
        if (column < 1) {
            throw new ServiceException(RequestException.DELETE_ERROR);
        }
        return JsonRequest.success(column);
    }

    /**
     * 根据用户ID查询课程表信息
     *
     * @param userId 用户ID
     * @return JSON
     */
    @Override
    @Cacheable(value = CacheKeysConstants.CourseKeys.COURSE_USER_ARRAY, key = "#userId")
    public JsonRequest<List<Course>> lookCourseByUser(Long userId) {
        List<CourseUser> courseUsers = courseUserService.list(Wrappers
                .lambdaQuery(CourseUser.class)
                .eq(CourseUser::getUserId, userId));
        List<Long> courseIds = courseUsers
                .stream()
                .map(CourseUser::getCourseId)
                .toList();
        return JsonRequest.success(listByIds(courseIds));
    }

    /**
     * 添加用户课程关联
     *
     * @param courseUser 用户课程关联
     * @return JSON
     */
    @Override
    @CacheEvict(value = CacheKeysConstants.CourseKeys.COURSE_USER_ARRAY, allEntries = true)
    public JsonRequest<Boolean> addCourseUser(CourseUser courseUser) {
        return JsonRequest.success(courseUserService.save(courseUser));
    }

    /**
     * 删除用户关联
     *
     * @param ids 用户关联ID列表
     * @return JSON
     */
    @Override
    @CacheEvict(value = CacheKeysConstants.CourseKeys.COURSE_USER_ARRAY, allEntries = true)
    public JsonRequest<Boolean> removeCourseUser(List<Long> ids) {
        return JsonRequest.success(courseUserService.removeBatchByIds(ids));
    }

}